package com.tul.exercise.base.operator.egs;


import org.junit.jupiter.api.Test;

import java.util.Random;

import static com.tul.exercise.base.utils.Print.*;

/**
 * @Description 《java编程思想》第3章 示例10：
 * <p>
 * 位移运行符
 **/
public class eg_10_BitManipulation {
    @Test
    public void test() {
        Random rand = new Random(47);


        printBinaryInt("-1", -1);
        printBinaryInt("+1", +1);

        int maxpos = 2147483647;
        printBinaryInt("maxpos", maxpos);

        int maxneg = -2147483648;
        printBinaryInt("maxneg", maxneg);

        int i = rand.nextInt();
        printBinaryInt("i", i);
        printBinaryInt("~i", ~i);
        printBinaryInt("-i", -i);

        int j = rand.nextInt();
        printBinaryInt("j", j);

        printBinaryInt("i & j", i & j);
        printBinaryInt("i | j", i | j);
        printBinaryInt("i ^ j", i ^ j);

        printBinaryInt("i << 5", i << 5);
        printBinaryInt("i >> 5", i >> 5);
        printBinaryInt("(~i) >> 5", (~i) >> 5);
        printBinaryInt("i >>> 5", i >>> 5);
        printBinaryInt("(~i) >>> 5", (~i) >>> 5);


        printBinaryLong("-1L", -1L);
        printBinaryLong("+1L", +1L);

        long ll = 922_3372_0368_5477_5807L;
        printBinaryLong("maxpos", ll);
        long lln = -922_3372_0368_5477_5808L;
        printBinaryLong("maxneg", lln);

        long l = rand.nextLong();
        long m = rand.nextLong();
        printBinaryLong("l", l);
        printBinaryLong("~l", ~l);
        printBinaryLong("-l", -l);

        printBinaryLong("m", m);

        printBinaryLong("l & m", l & m);
        printBinaryLong("l | m", l | m);
        printBinaryLong("l ^ m", l ^ m);

        printBinaryLong("l << 5", l << 5);
        printBinaryLong("l >> 5", l >> 5);
        printBinaryLong("(~l) >> 5", (~l) >> 5);
        printBinaryLong("l >>> 5", l >>> 5);
        printBinaryLong("(~l) >>> 5", (~l) >>> 5);
    }

    @Test
    public void exercise1() {
        long maxLong = Long.MAX_VALUE;
        print("maxLong=" + maxLong);
        printBinaryLong("maxLong", maxLong);

        long m = -0xA0_00_00_00_00_00_00_00L;
        print("m=" + m);

        //0L
        long n = -0x00_00_00_00_00_00_00_00L;
        print("n=" + n);
        printBinaryLong("n", n);


        // 110000000000000000000000000000000000000000000000000000000000000
        printBinaryLong("m", m);
        printBinaryLong("m>>1", m >> 1);
        printBinaryLong("m>>>1", m >>> 1);
        printBinaryLong("m<<1", m << 1);
        //printBinaryLong("m<<<1", m<<1);

        // 1L 循环左移
        printBinaryLong("1L", 1L);
        for (int i = 0; i <= 64; i++) {
            printBinaryLong("1<<" + i, 1L << i);
        }

        // -1L 循环左移
        printBinaryLong("-1L", -1L);
        for (int i = 0; i <= 64; i++) {
            printBinaryLong("-1<<" + i, -1L << i);
        }

    }

    @Test
    public void exercise2() {

        // 0x7fffffffffffffffL
        long maxLong = Long.MAX_VALUE;
        printBinaryLong("maxLong", maxLong);

        // 00x8000000000000000L
        long minLong = Long.MIN_VALUE;
        printBinaryLong("minLong", minLong);

        long minLong2 = 0x8000_0000_0000_0000L;
        printBinaryLong("minLong2", minLong2);



        // 2305843009213693952
        long m = +1L << 62;


        printBinaryLong("m", m);
        for (int i = 1; i < 63; i++) {
            printBinaryLong("m >> " + i + " ", m >> i);
        }


        //-9223372036854775808
        long n = 0x80_00_00_00_00_00_00_00L;
        printBinaryLong("n", n);
        for (int i = 1; i < 63; i++) {
            printBinaryLong("n >> " + i + " ", n >> i);
        }

        long k = -0x80_00_00_00_00_00_00_00L;
        printBinaryLong("k", k);
    }

    @Test
    public void exercise3() {

        // Integer.MAX_VALUE
        int maxInt = 0x7fff_ffff;
        println(maxInt + "," + Integer.toBinaryString(maxInt));
       printBinaryInt("maxInt",maxInt);

        int maxInt2 = Integer.parseInt(Integer.toBinaryString(maxInt), 2);
        printBinaryInt("maxInt2",maxInt2);

    }

    @Test
    public void exercise4() {

        println("1.0f " + "," + Float.toHexString(1.0f));
        println("1.001f " + "," + Float.toHexString(1.001f));

        println("1.001f " + "," + Float.floatToIntBits(1.001f));

        float f = 123.456f;

        int i = Float.floatToIntBits(f);

        System.out.println(i);

        float f2 = Float.intBitsToFloat(i);

        System.out.println(f2);
    }
}
